package test;

import java.awt.image.BufferedImage;  
import java.io.File;  
  
import javax.swing.Icon;  
import javax.swing.ImageIcon;  
import javax.swing.filechooser.FileSystemView;  
import javax.swing.plaf.IconUIResource;  
  
import org.eclipse.core.runtime.Platform;  
import org.eclipse.jface.dialogs.Dialog;  
import org.eclipse.jface.dialogs.IDialogConstants;  
import org.eclipse.swt.SWT;  
import org.eclipse.swt.events.SelectionAdapter;  
import org.eclipse.swt.events.SelectionEvent;  
import org.eclipse.swt.graphics.Image;  
import org.eclipse.swt.graphics.ImageData;  
import org.eclipse.swt.layout.FormAttachment;  
import org.eclipse.swt.layout.FormData;  
import org.eclipse.swt.layout.FormLayout;  
import org.eclipse.swt.widgets.Composite;  
import org.eclipse.swt.widgets.Control;  
import org.eclipse.swt.widgets.Display;  
import org.eclipse.swt.widgets.Event;  
import org.eclipse.swt.widgets.Label;  
import org.eclipse.swt.widgets.Listener;  
import org.eclipse.swt.widgets.Shell;  
import org.eclipse.swt.widgets.Tree;  
import org.eclipse.swt.widgets.TreeItem;  
import org.eclipse.ui.internal.UIPlugin;  
/** 
 * <p> 
 * Title: MultiDirectoryDialog.java 
 * </p> 
 * <p> 
 * Description: 文件选择框，支持多选 
 * </p> 
 *  
  */  
public class MultiDirectoryDialog extends Dialog {  
  
    // 菜单提示  
    private String message = "";  
    private Shell parent;  
    // 列表树  
    private Tree tree;  
    // 用来获取系统文件的相关信息  
    private FileSystemView fsv;  
  
    // 用来存放选择的文件夹,用分号隔开  
    private StringBuilder resultFile = new StringBuilder("");  
  
    /** 
     * 构造方法 
     *  
     * @param parent 
     *            父类 
     */  
    public MultiDirectoryDialog(Shell parent) {  
        super(parent);  
        this.parent = parent;  
    }  
  
    /* 
     * (non-Javadoc) 
     *  
     * @see 
     * org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets 
     * .Composite) 
     */  
    protected Control createDialogArea(Composite parent) {  
  
        parent.setDragDetect(false);  
        Composite container = (Composite) super.createDialogArea(parent);  
        container.setLayout(new FormLayout());  
  
        final Label showTipLabel = new Label(container, SWT.NONE | SWT.MULTI);  
        showTipLabel.setText(message);  
        final FormData fd_showTipLabel = new FormData();  
        fd_showTipLabel.top = new FormAttachment(0, 15);  
        fd_showTipLabel.bottom = new FormAttachment(0, 32);  
        fd_showTipLabel.right = new FormAttachment(0, 170);  
        fd_showTipLabel.left = new FormAttachment(0, 30);  
        showTipLabel.setLayoutData(fd_showTipLabel);  
  
        final Composite treeComposite = new Composite(container, SWT.BORDER);  
        treeComposite.setDragDetect(false);  
        treeComposite.setLayout(new FormLayout());  
        // treeComposite.set  
        // scrolledComposite.setAlwaysShowScrollBars(true);  
        final FormData fd_scrolledComposite = new FormData();  
        fd_scrolledComposite.right = new FormAttachment(100, 0);  
        fd_scrolledComposite.left = new FormAttachment(0, 0);  
        fd_scrolledComposite.bottom = new FormAttachment(100, 0);  
        fd_scrolledComposite.top = new FormAttachment(0, 50);  
        treeComposite.setLayoutData(fd_scrolledComposite);  
        // 新建树  
        tree = new Tree(treeComposite, SWT.DEFAULT);  
        final FormData fd_tree = new FormData();  
        fd_tree.left = new FormAttachment(0, 5);  
        fd_tree.bottom = new FormAttachment(0, 300);  
        fd_tree.top = new FormAttachment(0, 0);  
        fd_tree.right = new FormAttachment(0, 400);  
        tree.setLayoutData(fd_tree);  
        treeComposite.setData(tree);  
  
        // 为树增加单击方法  
        tree.addListener(SWT.Expand, new Listener() {  
            public void handleEvent(final Event event) {  
                final TreeItem item = (TreeItem) event.item;  
                TreeItem[] items = item.getItems();  
                for (int i = 0; i < items.length; i++) {  
                    if (items[i].getData() != null)  
                        return;  
                    items[i].dispose();  
                }  
  
                // 初始化该文件下的节点  
                File file = (File) item.getData();  
                File[] childFile = file.listFiles();  
                for (File sfile : childFile) {  
                    if (sfile.isDirectory()) {  
                        initFile(item, sfile);  
                    }  
                }  
  
            }  
  
        });  
  
        // 获取系统文件信息  
        fsv = FileSystemView.getFileSystemView();  
        File[] file = fsv.getRoots();  
  
        TreeItem item = new TreeItem(this.tree, SWT.NONE);  
        String fileName = file[0].getName();  
        item.setText(fileName);  
        item.setData(file[0]);  
        Image img = getIcon(file[0]);  
        if (img != null)  
            item.setImage(img);  
        // new TreeItem(item, 0);  
        listFile(item, file[0], 1);  
        return container;  
    }  
  
    /** 
     * 本类用来初始化文件夹下的文件夹 
     *  
     * @param treeitem 
     *            父节点 
     * @param file 
     *            要初始化的文件夹 
     * @param flag 
     *            0：由外部调用，其它：递归调用 
     */  
    private void listFile(TreeItem treeitem, File file, int flag) {  
        File[] childFile = file.listFiles();  
        if (flag == 0) {// 如果是外部调用，则再初始一级，以用来显示图标前的十一号。  
            for (File sfile : childFile) {  
                if (sfile.isDirectory()) {  
                    // 初始化item的相关数据  
                    TreeItem item = initFile(treeitem, sfile);  
                    // 初始化下一级item  
                    listFile(item, sfile, 1);// 只多这一行  
                }  
            }  
  
        } else {// 如果是自身调用，则说明已经为第二级文件夹，不需要再初始化下一级  
            for (File sfile : childFile) {  
                if (sfile.isDirectory()) {  
                    initFile(treeitem, sfile);  
                }  
            }  
        }  
    }  
  
    /** 
     * 初始化item的相关数据 
     *  
     * @param treeitem 
     *            要初始化item的父item 
     * @param file 
     *            初始化item对应的file 
     * @return 初始化后的item 
     */  
    private TreeItem initFile(TreeItem treeitem, File file) {  
  
        TreeItem item = new TreeItem(treeitem, SWT.NONE);  
        item.setText(fsv.getSystemDisplayName(file));  
  
        item.setData(file);  
        Image img = getIcon(file);  
        if (img != null)  
            item.setImage(img);  
        // 如果还是文件夹，则加一个空节点，以使十号显示出来  
        if (file.isDirectory())  
            new TreeItem(item, 0);  
        return item;  
    }  
  
    /** 
     * 获取文件图标 
     *  
     * @param file 
     *            要获取图标的文件 
     * @return 图标 
     */  
    public Image getIcon(File file) {  
        ImageData imageData = null;  
        // 取得awt的icon对像并转化为swt的image对像  
        Icon icon = fsv.getSystemIcon(file);  
        if (icon instanceof IconUIResource) {  
        } else {  
            // BufferedImage bi = ImageConvertor.getBufferedImage((ImageIcon)  
            // icon);  
            // imageData = ImageConvertor.getImageData(bi);  
            // imageData = new Image(Display.getDefault(),50,50).getImageData();  
        }  
        Image img = null;  
  
        if (imageData != null)  
            img = new Image(parent.getDisplay(), imageData);  
  
        return img;  
    }  
  
    /** 
     * Create contents of the button bar 
     *  
     * @param parent 
     */  
    @Override  
    protected void createButtonsForButtonBar(Composite parent) {  
        createButton(parent, IDialogConstants.OK_ID, "确定", true);  
        createButton(parent, IDialogConstants.CANCEL_ID, "取消", false);  
    }  
  
    /** 
      SWT.MULTI创建出可以让用户作出多重选取的tree。SWT.CHECK样式的Tree会产生checkbox的Tree。如果使用了SWT.CHECK的样式，就需要判断哪些项目被选取了。通过调用TreeItem的getChecked()来判断某个项目是否被checked。下面的程序在循环中判断每个TreeItem的状态： 
        TreeItem[] tia=t.getItems(); 
          for(int i=0;i<tia.length;i++){ 
           if(tia[i].getChecked()){ 
            System.out.print("Checked"); 
           } 
          TreeItem []child=tia[i].getItems(); 
          for(int n=0;n<child.length;n++) 
           if(child[n].getChecked()) 
            System.out.print("Checked"); 
            } 
         
        以上的代码只能用在仅有一层子项目的tree上。多层的tree需要循环运算来处理。 
         
        SWT.CHECK样式的Tree对象在你需要让用户对Tree作出多重选取但又不想要SWT.MULTI模式的额外成本的时候是合适的（但若是要使用选取出的TreeItem来采取某些像是产生list内容这样的动作时则不适用） 
     */  
    protected void buttonPressed(int buttonId) {  
        if (buttonId == IDialogConstants.OK_ID) {  
  
            TreeItem[] treeitem = tree.getItems();  
            for (int i = 0; i < treeitem.length; i++) {  
                if (treeitem[i].getChecked()) {  
                    if (treeitem[i].getChecked()) {  
                        File file = (File) treeitem[i].getData();  
                        resultFile.append(file.getPath()).append(";");  
                    }  
                }  
                TreeItem[] child = treeitem[i].getItems();  
                for (int n = 0; n < child.length; n++)  
                    if (child[n].getChecked()) {  
                        File file = (File) child[n].getData();  
                        resultFile.append(file.getPath()).append(";");  
                    }  
            }  
            System.out.println(resultFile.toString());  
        }  
        super.buttonPressed(buttonId);  
    }  
  
    /** 
     * 设置 message 
     *  
     * @return 
     */  
    public String getMessage() {  
        return message;  
    }  
  
    /** 
     * 获取message 
     *  
     * @param message 
     */  
    public void setMessage(String message) {  
        this.message = message;  
    }  
  
    /** 
     * @return 
     */  
    public StringBuilder getResultFile() {  
        return resultFile;  
    }  
  
    /** 
     * @param resultFile 
     */  
    public void setResultFile(StringBuilder resultFile) {  
        this.resultFile = resultFile;  
    }  
  
    public static void main(String[] args) {  
        final Display display = Display.getDefault();  
        final Shell shell = new Shell(display, SWT.ON_TOP | SWT.CLOSE);  
        shell.setSize(327, 253);  
        Dialog dialog = new MultiDirectoryDialog(shell);  
        if (dialog.open() == IDialogConstants.OK_ID) {// 是否单击“确定”按钮  
            System.out.println("helo");  
        }  
  
        shell.open();  
        while (!shell.isDisposed()) {  
            if (!display.readAndDispatch())  
                display.sleep();  
        }  
        display.dispose();  
  
    }  
}  